﻿#include<stdio.h>
#include<conio.h>
#include<Winsock2.h>
#include<windows.h>

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

#include <boost/serialization/vector.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

using namespace std;
#include "Structs.h"

namespace boost {
namespace serialization {

template<class Archive>
void serialize(Archive & ar, sometype &g, const unsigned int version)
{
	//for(int i=0;i<10;++i)
	ar & g.ar;//[i];
}

template<class Archive>
void serialize(Archive & ar, struct2 &g, const unsigned int version)
{
	ar & g.x;
	ar & g.y;
}

template<class Archive>
void serialize(Archive & ar, struct1 & g, const unsigned int version)
{
	ar & g.a;
	ar & g.b;
}

} // namespace serialization
} // namespace boost

void HookFunc(struct2* s2,struct1 s1)
{	//PACK//
				func_in_inout funcininout(s2,s1);
				vector<char> buf;

				Serialize(GetCurrentThreadId(),"HookFunc",funcininout,&buf);
	  //UNPACK//
				func_in_inout funcininout_r;
				struct1 s11;
				struct2 *s22;
				char FuncName[MAX_PATH+1];
				DWORD TIDr=0;

				DeserializeStdHeader(&TIDr,FuncName,&buf);
				Deserialize(funcininout_r,&buf);//Неэфективно. В этой функции приходится ещё раз десереализовывать 
						//стандартный заголовок, чтобы дойти до аргументов.
						//Этого можно избежать, если обойтись без функций, а просто использовать их код, они маленькие.
				
				cout<<"FuncName "<<FuncName<<endl;
				cout<<"TIDr "<<TIDr<<endl;
				s22=funcininout_r.s2_;
				s11=funcininout_r.s1_;

				cout<<"S1 a "<<s11.a<<" b "<<s11.b<<endl;
				if(s22)
				{
				cout<<"S2 ";
				if(s22->x)
				{
					cout<<"ar ";
					for(int i=0;i<10;++i)
						cout<<(int)s22->x->ar[i]<<" ";
				} 
				cout<<"y "<<s22->y<<endl;
				}
}

void main()
{
	sometype st={49,50,51,52,53,54,55,56,57,58};
	struct1 st1={10,20.1};
	struct2 st2={&st,200};
	
	HookFunc(&st2,st1);
getch();
}
/*
Цель протокола - передавать значения аргументов между клиентом и сервером, возвращаемые знач. и указание какую функцию вызывать на клиенте.
Для этого выделяем непрерывный участок памяти(datatosend), который заполним информацией и перешлём
Структура информации в посылаемом на клиент участке:
 1)Сначала идёт ANSI null terminated string с именем функции.
 2)Дальше идут значения аргументов в последовательности слева направо.
	Если один из аргументов указатель, то передавать его на клиент нет смысла, поэтому
	вместо него должно быть значение.

	 а)Если оригинальная функция(которую мы хучили) не будет считывать информацию по аргументу,
		то такой аргумент вобще не будет записывать в datatosend. В MSDN такие аргументы обозначены __out.	
		
	 б)Если оригинальная функция(которую мы хучили)  будет считывать информацию по аргументу,
		то вместо указателя будет записываться его содержимое. В MSDN такие аргументы обозначены __in.	
		
	 с)Если оригинальная функция(которую мы хучили) будет и считывать и записывать в аргумент,
		то он должен записываться.

Структура информации в принимаемом от клиент участке:
1)Значения аргументов в последовательности слева направо.(ANSI null terminated string с именем функции отсутствует)

	а)Если аргумент __out, то он будет присутствовать в принимаемой информации

	б)Если аргумент __in, то он будет отсутствовать в принимаемой информации

	c)Если аргумент __inout, то он будет присутствовать в принимаемой информации

Аргументы записываются в "память для отправки" функцией addarg
Если аргумент - структура, в которой есть указатели на другие структуры, то главную структуру нельзя просто
записать в память с пом memcpy так как в память запишутся значения полей-указателей, а не данные
на которые они указывают. Для таких структур необходимо перегружать ф. addarg как показано в примере.

Если структура не содержит указателей, то её можно записать с пом memcpy, но для поддержания
единообразного интерфейса наверное необходимо перегружать addarg и для таких структур.

Если мы создали addarg, то тут же необходимо создать ф. getarg.

Эти функции делаютсяпо шаблону очень легко. Две последние строки return и written можно вообще макросом сделать.

Поэтому если возникнет необходимость добавить ещё функции хука, то это не должно вызвать затруднения.

		*/